#include "apue.h"

static void sig_int(int);

int main(void) {
    sigset_t setnew, setwait, setold;

    pr_mask("program start: ");

    if (signal(SIGINT, sig_int) == SIG_ERR)
        err_sys("signal(SIGINT) error");
    sigemptyset(&setnew);
    sigaddset(&setnew, SIGINT);
    sigemptyset(&setwait);
    sigaddset(&setwait, SIGUSR1);

    /**
     * Block SIGINT and save current signal mask
     */
    if (sigprocmask(SIG_BLOCK, &setnew, &setold) < 0) {
        err_sys("SIG_BLOCK error");
    }
    // critical region of code
    pr_mask("in critical region: ");

    /**
     * Pause, allowing all signals except SIGUSR1
     */
    if (sigsuspend(&setwait) != -1)
        err_sys("sigsuspend error");

    pr_mask("back from sigsuspend: ");

    /**
     * Reset signal mask which unblocks SIGINT
     */
    if (sigprocmask(SIG_SETMASK, &setold, NULL) < 0) {
        err_sys("SIG_SETMASK error");
    }

    /**
     * And continue processing...
     */
    pr_mask("program exit: ");
}

static void sig_int(int) {
    pr_mask("\nin sig_int: ");
}
